package model;

import java.io.Serializable;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

/**
 * Class represents the datastructure in which Bills for auctions of users are
 * stored.
 */
public class Bill implements Serializable {

	private static final long serialVersionUID = 8799886529137940281L;
	private List<BillEntry> entries;
	private String username;

	public Bill(String username) {
		this.entries = Collections.synchronizedList(new ArrayList<BillEntry>());
		this.username = username;
	}

	/**
	 * Adds a new Entry for a auction that shall be billed.
	 * 
	 * @param auctionID
	 *            The ID of the auction
	 * @param strikePrice
	 *            The price the auction ended with.
	 * @param feeFixed
	 *            The fix fee for the auction.
	 * @param feeVariable
	 *            the variable fee fot the auction.
	 */
	public void addEntry(long auctionID, double strikePrice, double feeFixed,
			double feeVariable) {
		this.entries.add(new BillEntry(auctionID, strikePrice, feeFixed,
				feeVariable));
	}

	public String getUsername() {
		return this.username;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		String result = "auction_ID strike_price fee_fixed fee_variable fee_total\n";
		Collections.sort(this.entries);
		for (BillEntry entry : this.entries) {
			result += entry.toString();
		}
		return result.substring(0, result.length() - 1);
	}

	/**
	 * Creates a string that consists of a specific number of whitespaces.
	 * 
	 * @param num
	 *            The number of whitespaces the string shall have.
	 * @return The resulting String.
	 */
	private String getSpaces(int num) {
		String result = "";
		if (num > 1) {
			for (int i = 0; i < num; i++) {
				result += " ";
			}
			return result;
		}
		return " ";

	}

	/**
	 * Inner class BillEntry represents an entry in the list of entries of the
	 * Bill class, where each entry represents a billed auction.
	 */
	private class BillEntry implements Comparable<BillEntry>, Serializable {

		private static final long serialVersionUID = -5513244789409727056L;
		private long auctionID;
		private double strikePrice;
		private double feeFixed;
		private double feeVariable;

		public BillEntry(long auctionID, double strikePrice, double feeFixed,
				double feeVariable) {
			this.auctionID = auctionID;
			this.strikePrice = strikePrice;
			this.feeFixed = feeFixed;
			this.feeVariable = feeVariable;
		}

		public long getAuctionId() {
			return this.auctionID;
		}

		public double getFeeTotal() {
			double fixed = this.feeFixed * 100;
			fixed = Math.round(fixed);
			fixed /= 100;
			double variable = this.feeVariable * 100;
			variable = Math.round(variable);
			variable /= 100;
			return fixed + variable;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#toString()
		 */
		@Override
		public String toString() {
			Long id = new Long(this.auctionID);
			Double strike = new Double(this.strikePrice);
			Double fixed = new Double(this.feeFixed);
			fixed *= 100;
			fixed = new Double(Math.round(fixed));
			fixed /= 100;
			Double variable = new Double(this.feeVariable);
			variable *= 100;
			variable = new Double(Math.round(variable));
			variable /= 100;
			Double total = new Double(this.getFeeTotal());
			return id + getSpaces(11 - id.toString().length()) + strike
					+ getSpaces(13 - strike.toString().length()) + fixed
					+ getSpaces(10 - fixed.toString().length()) + variable
					+ getSpaces(13 - variable.toString().length()) + total
					+ "\n";
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Comparable#compareTo(java.lang.Object)
		 */
		@Override
		public int compareTo(BillEntry other) {
			if (this.getAuctionId() < other.getAuctionId()) {
				return -1;
			} else if (this.getAuctionId() > other.getAuctionId()) {
				return 1;
			}
			return 0;
		}
	}

}
